package com.by.factory;

/**
 * @version 1.0
 * @Author 彭彦彬
 * @Date 2025/4/8 20:17
 * @注释
 */
import com.by.annotion.Autowired;
import com.by.bean.BeanDefinition;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class SimpleBeanFactory {
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
    private Map<String, Object> singletonBeans = new HashMap<>();

    // 注册 Bean 定义
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }

    // 获取 Bean 实例
    public Object getBean(String beanName) throws Exception {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) {
            throw new IllegalArgumentException("No bean named '" + beanName + "' is defined");
        }

        // 如果是单例模式
        if ("singleton".equals(beanDefinition.getScope())) {
            Object singletonBean = singletonBeans.get(beanName);
            if (singletonBean == null) {
                singletonBean = createBean(beanDefinition);
                singletonBeans.put(beanName, singletonBean);
            }
            return singletonBean;
        }

        // 如果是原型模式
        return createBean(beanDefinition);
    }

    // 创建 Bean 实例
    private Object createBean(BeanDefinition beanDefinition) throws Exception {
        Class<?> beanClass = beanDefinition.getBeanClass();
        Object bean = beanClass.getDeclaredConstructor().newInstance();

        // 自动注入依赖（简单实现）
        autowire(bean);

        return bean;
    }

    // 自动注入依赖
    private void autowire(Object bean) throws Exception {
        for (Field field : bean.getClass().getDeclaredFields()) { // 显式声明 Field 类型
            if (field.isAnnotationPresent(Autowired.class)) {
                field.setAccessible(true);
                Class<?> fieldType = field.getType();
                Object dependency = getBean(fieldType.getSimpleName());
                field.set(bean, dependency);
            }
        }
    }
}